#include<iostream>
#include<string>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <ctime>
#include <openssl/sha.h>
#include "sv_node.hpp"
#include "my570list.hpp"
#include "cs570.h"

using namespace std;


char* HomeDir1=NULL;
char* LogFilename1=NULL;
char* InitFilename1=NULL;

extern string LogLocation;
extern struct timeval tim;
extern pthread_mutex_t log_lock;


extern My570List* NeighborList;
extern My570List* SocketList;
extern My570List* EventQ;
extern My570List* DBase;
extern pthread_mutex_t PrintLock;
extern list<GlobalList_Elem*> GlobalList;
extern ini_info* i1;
extern unsigned char* UOIDstr;
extern char hostname[512];
extern pthread_attr_t attr;
int MyTimerFlag;
int MyTimerCount = 0;
unsigned long seq_no=(unsigned long)1;
extern unsigned char *node_instance_id;
extern int Duplicate;
extern int dupGlobal;
extern int activeconnection;
extern pthread_mutex_t SocketList_lock; //= PTHREAD_MUTEX_INITIALIZER;
extern pthread_mutex_t GlobalList_lock;
extern pthread_mutex_t NeighborList_lock; //= PTHREAD_MUTEX_INITIALIZER;
extern pthread_mutex_t nam_lock;
extern My570List* nam;

//list<InitNeighborList_Elem*> InitNeighborList;

//.....................signals
extern sigset_t sigalrm;
extern struct sigaction act;
extern int AutoShutDown;

void alrm2(int sig)
{

	//cout<<"Signal SIGALRM on NonBeaconJoin received, the program will gracefully terminate now!"<<endl;

      MyTimerFlag = 1;
      AutoShutDown=1;
	
	//exit(1);

}
//...............signals

My570List*  InitNeighborList = new My570List();
string InitLocation;

GlobalList_Elem::GlobalList_Elem()
{
	Port=0;
	//ListP=NULL;
	Temp=0;
	Socket=0;
	pthread_mutex_init(&EventQlock,NULL);
	pthread_cond_init(&EventQ_cv,NULL);

}

Flood_Elem::Flood_Elem()
{
	HostLocation=0;
	Port=0;
	UOID=NULL;
	Distance=0;
	respUOID=NULL;
	respPort=0;
}

beacon::beacon()
{
	BeaconName=NULL;
	BeaconPort=0;
}

NeighborList_Elem::NeighborList_Elem()
{
	UOID=NULL;
	HostPort=0;
}

InitNeighborList_Elem::InitNeighborList_Elem()
{
	Distance=0;
	Port=0;
}
ini_info::ini_info()
{
    Port=0;
    Location=0;
    HomeDir=NULL;
    LogFilename=NULL;
	AutoShutdown=0;
	TTL=0;
	MsgLifetime=0;
	GetMsgLifetime=0;
	InitNeighbors=0;
	JoinTimeout=0;
	KeepAliveTimeout=0;
	MinNeighbors=0;
	NoCheck=0;
	CacheProb=0.0;
	StoreProb=0.0;
    NeighborStoreProb=0.0;
	CacheSize=0;

	//BeaconList=new My570List();

}
//ini_info functions
void removeAllWhite (string &str)
{
    string temp;
    for (unsigned int i = 0; i < str.length(); i++)
       if (str[i] != ' ') temp += str[i];
       str = temp;
}
///////////////////////
ini_info* ini_parser(const char* filename)
{
	//object created
	ini_info* i_obj=new ini_info();

	FILE *fp = fopen(filename,"r");
	if(fp==NULL){
		cerr<<"File can not be opened; the program will terminate now."<<endl;
		exit(1);
	}
        // Parsing declarations
		string s1="Port";
		string s2="Locaion";
		string s3="HomeDir";
		string s4="LogFilename";
		string s5="AutoShutdown";
		string s6="TTL";
		string s7="MsgLifetime";
		string s8="GetMsgLifetime";
		string vstring;
		string temp;
		int i=0;
		int beaconflag=0;
		
		char mystring[1000];
		while(fgets(mystring,sizeof(mystring),fp)!=NULL)
		{
	//		cout<<mystring<<endl;
			vstring = string(mystring);
		    removeAllWhite(vstring);

			if(beaconflag==0){
  
			i=vstring.find_first_of("=");
			if(i!=-1){
            string evaluate = vstring.substr(0,i);
			//cout<<i<<endl;
			//cout<<"EEEEEEEEEE"<<evaluate<<endl;
			 if(evaluate.compare("Port")==0){
				 temp.clear();
				 //cout<<vstring.length()<<endl;
				 temp=vstring.substr(i+1,vstring.length()-i-1);
				// cout<<"ppppp"<<vstring.substr(i+1,vstring.length()-i-1)<<endl;
				 i_obj->Port=atoi(temp.c_str());
		//		 cout<<i_obj->Port<<endl;
				 //exit(1);
			 }
			 if(evaluate.compare("Location")==0){
				 temp.clear();
				 temp=vstring.substr(i+1,vstring.length()-i-1);
				 i_obj->Location=atoi(temp.c_str());
		//		 cout<<i_obj->Location<<endl;
			 }
			 if(evaluate.compare("HomeDir")==0){
				 temp.clear();
				 temp=vstring.substr(i+1,vstring.length()-i-1);
				 i_obj->HomeDir= temp.c_str();
				 HomeDir1=new char[temp.length()+1];
				 strcpy(HomeDir1,temp.c_str());//,temp.length());
				 //cout<<"homedir inside inip "<<i_obj->HomeDir;
			 }
			 if(evaluate.compare("LogFilename")==0){
				 temp.clear();
				 temp=vstring.substr(i+1,vstring.length()-i-1);
				 i_obj->LogFilename=temp.c_str();
				 LogFilename1=new char[temp.length()+1];
				 strcpy(LogFilename1,temp.c_str());
				// cout<<"logfilename inside inip "<<i_obj->LogFilename<<endl;
			 }
			 if(evaluate.compare("AutoShutdown")==0){
				 temp.clear();
				 temp=vstring.substr(i+1,vstring.length()-i-1);
				 i_obj->AutoShutdown=atoi(temp.c_str());
		//		 cout<<i_obj->AutoShutdown<<endl;
			 }
			 if(evaluate.compare("TTL")==0){
				 temp.clear();
				 temp=vstring.substr(i+1,vstring.length()-i-1);
				 i_obj->TTL=atoi(temp.c_str());
		//		 cout<<i_obj->TTL<<endl;
			 }
			 if(evaluate.compare("MsgLifetime")==0){
				 temp.clear();
				 temp=vstring.substr(i+1,vstring.length()-i-1);
				 i_obj->MsgLifetime=atoi(temp.c_str());
		//		 cout<<i_obj->MsgLifetime<<endl;
			 }
			 if(evaluate.compare("GetMsgLifetime")==0){
				 temp.clear();
				 temp=vstring.substr(i+1,vstring.length()-i-1);
				 i_obj->GetMsgLifetime=atoi(temp.c_str());
		//		 cout<<i_obj->GetMsgLifetime<<endl;
			 }
			 if(evaluate.compare("InitNeighbors")==0){
				 temp.clear();
				 temp=vstring.substr(i+1,vstring.length()-i-1);
				 i_obj->InitNeighbors=atoi(temp.c_str());
		//		 cout<<"in "<<i_obj->InitNeighbors<<endl;
			 }
			 if(evaluate.compare("JoinTimeout")==0){
				 temp.clear();
				 temp=vstring.substr(i+1,vstring.length()-i-1);
				 i_obj->JoinTimeout=atoi(temp.c_str());
		//		 cout<<"jt "<<i_obj->JoinTimeout<<endl;
			 }
			 if(evaluate.compare("KeepAliveTimeout")==0){
				 temp.clear();
				 temp=vstring.substr(i+1,vstring.length()-i-1);
				 i_obj->KeepAliveTimeout=atoi(temp.c_str());
		//		 cout<<"kat "<<i_obj->KeepAliveTimeout<<endl;
			 }
			 if(evaluate.compare("MinNeighbors")==0){
				 temp.clear();
				 temp=vstring.substr(i+1,vstring.length()-i-1);
				 i_obj->MinNeighbors=atoi(temp.c_str());
		//		 cout<<"MinN "<<i_obj->MinNeighbors<<endl;
			 }
			 if(evaluate.compare("NoCheck")==0){
				 temp.clear();
				 temp=vstring.substr(i+1,vstring.length()-i-1);
				 i_obj->NoCheck=atoi(temp.c_str());
		//		 cout<<"NOC "<<i_obj->NoCheck<<endl;
			 }
			 if(evaluate.compare("CacheProb")==0){
				 temp.clear();
				 temp=vstring.substr(i+1,vstring.length()-i-1);
				 i_obj->CacheProb=atof(temp.c_str());
		//		 cout<<"CAP "<<i_obj->CacheProb<<endl;
			 }
			 if(evaluate.compare("StoreProb")==0){
				 temp.clear();
				 temp=vstring.substr(i+1,vstring.length()-i-1);
				 i_obj->StoreProb=atof(temp.c_str());
		//		 cout<<"StP "<<i_obj->StoreProb<<endl;
			 }
			 if(evaluate.compare("NeighborsStotrProb")==0){
				 temp.clear();
				 temp=vstring.substr(i+1,vstring.length()-i-1);
				 i_obj->NeighborStoreProb=atof(temp.c_str());
		//		 cout<<"NSP "<<i_obj->NeighborStoreProb<<endl;
			 }
			 if(evaluate.compare("CacheSize")==0){
				 temp.clear();
				 temp=vstring.substr(i+1,vstring.length()-i-1);
				 i_obj->CacheSize=atoi(temp.c_str());
		//		 cout<<"Cachesize "<<i_obj->CacheSize<<endl;
			 }

	     		}else{
					char* pch;
					pch=strstr(vstring.c_str(),"[beacons]");
					if(pch!=NULL){
				       beaconflag=1;
		//		       cout<<"Beaconflag"<<endl;
			        }   
            
     		    }
			}else{
		//		cout<<"Inside beacon"<<endl;
				char* pch1;
				pch1=strstr(vstring.c_str(),"Retry");
				
				if(pch1!=NULL){
                    i=vstring.find_first_of("="); 
					temp.clear();
					temp=vstring.substr(i+1,vstring.length()-i-1);
					i_obj->Retry=atoi(temp.c_str());
		//			cout<<"Retry "<<i_obj->Retry<<endl;
                 
				}else{
					beacon b;
					i=vstring.find_first_of(":");
					b.BeaconName=(vstring.substr(0,i)).c_str();
					//cout<<"bbbbb "<<b.BeaconName<<endl;
					temp.clear();
					temp=vstring.substr(i+1,vstring.length()-i-2);
					b.BeaconPort=atoi(temp.c_str());
					//cout<<"bnbnbn "<<b.BeaconPort<<endl;
					i_obj->BeaconList.push_back(b);
					list<beacon>::iterator it;
					it = i_obj->BeaconList.begin();
					//cout<<"___+________"<<endl;
					//cout<<(*it).BeaconPort<<" ";
					//cout<<(*it).BeaconName<<endl;
				}
				
			}

		}//end of while

	return i_obj;
}

////////////////////////////// ini_info completed ////

/////////////////////////////Functions///////////////

////Get_node_inst_id

unsigned char* Get_node_inst_id(char* hname,int hport,time_t time)
{
	char* buffer = new char[512];
	
	sprintf(buffer,"%s_%d_%ld",hname,hport,time);
	string temp=string(buffer);
    int k =temp.length();
	buffer[k+1]='\0';

	return (unsigned char*)buffer;
}

////GetUOID////

unsigned char *GetUOID(unsigned char *node_inst_id,const char *obj_type)
{
	
	//unsigned char* uoid_buf=(unsigned char*)malloc(SHA_DIGEST_LENGTH);
	//unsigned int uoid_buf_sz=sizeof(uoid_buf);

	unsigned char uoid_buf[SHA_DIGEST_LENGTH];
	unsigned int uoid_buf_sz=sizeof(uoid_buf);
//	static unsigned long seq_no=(unsigned long)1;
	char sha1_buf[SHA_DIGEST_LENGTH];
	char str_buf[104];

	//string mybuf=string(str_buf);
	//string mysha=string(sha1_buf);

	snprintf(str_buf, sizeof(str_buf), "%s_%s_%1ld",node_inst_id,obj_type, (long)seq_no++);
	SHA1((unsigned char*)str_buf,strlen(str_buf),(unsigned char*)sha1_buf);
	memset(uoid_buf,0,uoid_buf_sz);
	memcpy(uoid_buf, sha1_buf, min(uoid_buf_sz,sizeof(sha1_buf)));
    
/*    for(int i=0;i<20;i++)
	{
		printf("%02x",uoid_buf[i]);
	}
	cout<<endl;
  */ 
    
	//exit(1);
	unsigned char* myret = (unsigned char*)&uoid_buf;
    return myret;
}

//INTEGER LENGTH////
int intLength(int start) 
{ 
	int end = 0; 
	while(start > 0) 
	{ 
		start = start/10; 
		end++; 
    } 
	return end; 
} 

//---------------------------------- NEIGHBOR LIST DUPLICATE CHECK ---------------------------------------//

bool eval_Duplicate()
{
    int MemMap=100; 
	My570ListElem* elem = new My570ListElem();
	My570ListElem* curr = new My570ListElem();

	if(NeighborList->Length()<=1){return 1;}

	 //myList.end();
	/*unsigned char* local = new unsigned char[20];
	memset(local,'\0',20);*/
	curr=NeighborList->Last();
//	cout<<"Inside duplicate."<<endl;	
	/*for(elem=NeighborList->First();elem!=NULL;elem=NeighborList->Next(elem)){
	cout<<((NeighborList_Elem *)(elem->Obj()))->HostPort<<" in duplicate"<<endl;
    }*/

	//memcpy(&local[0],((NeighborList_Elem *)(elem->Obj()))->UOID,20);

	for(elem=NeighborList->First();elem!=NULL;elem=NeighborList->Next(elem))
	{
//		cout<<"Doning Memcompare"<<endl;
      if(elem==NeighborList->Last()){return 1;}
	  MemMap=memcmp(((NeighborList_Elem  *)(curr->Obj()))->UOID,((NeighborList_Elem *)(elem->Obj()))->UOID,20);
	  if(MemMap==0){ NeighborList->Unlink(NeighborList->Last()); return 0;}
    
	}
	return 1;
}

bool duplicateNode()
{
  //  int MemMap=100; 
	My570ListElem* elem = new My570ListElem();
	My570ListElem* curr = new My570ListElem();

	if(nam->Length()<=1){return 1;}

	
	curr=nam->Last();
    for(elem=nam->First();elem!=NULL;elem=nam->Next(elem))
	{
//		cout<<"Doning Memcompare"<<endl;
      if(elem==nam->Last()){return 1;}
	  
	   if((int)(curr->Obj()) == (int)(elem->Obj())){ 
        return 0;}
    
	}
	return 1;
}

int eval_Global()
{
	int memMap = 100;
	GlobalList_Elem *curr = new GlobalList_Elem();
	list<GlobalList_Elem*>::iterator elem;
	curr = GlobalList.back();
	if (GlobalList.size()<=1){return 1;}
	for (elem = GlobalList.begin();elem!= GlobalList.end();elem++ )
	{
//		cout<<"doing global compare"<<endl;
		if (*elem == GlobalList.back()){return 1;}
		
		memMap = memcmp(curr->UOID,(*elem)->UOID,20);
		if (memMap==0)
		{
			GlobalList.pop_back();
			return 0;
		}
	}
	return 1;
}
int eval_Global1()
{
	int memMap = 100;
	GlobalList_Elem *curr = new GlobalList_Elem();
	list<GlobalList_Elem*>::iterator elem;
	curr = GlobalList.back();
	if (GlobalList.size()<=1){return 1;}
	for (elem = GlobalList.begin();elem!= GlobalList.end();elem++ )
	{	
		if (((*elem)->Temp)==1 || ((*elem)->Temp)==2 )
		{
			GlobalList.remove((*elem));
		}else{
//		cout<<"doing global compare"<<endl;
		if (*elem == GlobalList.back()){return 1;}
		
		memMap = memcmp(curr->UOID,(*elem)->UOID,20);
		if (memMap==0)
		{
			GlobalList.pop_back();
			return 0;
		}
		}
	}
	return 1;
}
int eval_DBase()
{
	int MemMap=100;
	My570ListElem* elem = new My570ListElem();
	My570ListElem* curr = new My570ListElem();
	//cout<<"Inside DBase"<<endl;
	curr= DBase->Last();
	if(DBase->Length()==0){
	//	cout<<"No duplicate1"<<endl;
		return 1;}
	
	for(elem=DBase->First();elem!=NULL;elem=DBase->Next(elem))
	{
		//cout<<"Iteration"<<endl;
		if(elem==DBase->Last()){//cout<<"No Duplicate2"<<endl;
			return 1;}
		MemMap = memcmp((curr->Obj()),(elem->Obj()),20);
		if(MemMap==0){//cout<<"Duplicate found"<<endl;
		return 0;}
	}
	return 1;
}

void print_DBase()
{
/*	int iter=1;

	My570ListElem* temp = new My570ListElem();
	cout<<"______________DBase_____________________BEGIN________"<<endl;
	for(temp=NeighborList->First();temp!=NULL;temp=NeighborList->Next(temp))
	{
		cout<<"Iteration "<<iter<<endl;
		cout<<"UOID ";
		for(int iter1=0;iter1<20;iter1++){
			printf("%02x",((unsigned char)(temp->Obj()))[iter1]);}cout<<endl;
		iter++;
	}
	cout<<"__________________DBASE____________________________LIST PRINT END______"<<endl;
	return;
*/}

//------------------------------------------------------Print my list NeighborList BEGIN--------------------------------------------------------//
void print_NeighborList()
{
	int iter=1;
	My570ListElem* temp = new My570ListElem();

    cout<<"_______________NEIGHBORLIST_______________________________LIST PRINT BEGIN____"<<endl;
	for(temp=NeighborList->First();temp!=NULL;temp=NeighborList->Next(temp))
	{
		cout<<"Iteration "<<iter<<endl;
		cout<<"HostPort "<<((NeighborList_Elem*)(temp->Obj()))->HostPort<<endl;
		cout<<"UOID ";
		for(int iter1=0;iter1<20;iter1++){
			printf("%02x",(unsigned char)(((NeighborList_Elem*)(temp->Obj()))->UOID)[iter1]);}cout<<endl;
		iter++;
	}
	cout<<"__________________NEIGHBORLIST____________________________LIST PRINT END______"<<endl;
	return;
}
void print_GlobalList()
{
	int iter = 1;
	list<GlobalList_Elem*>:: iterator temp;
	cout<<"________________GLOBAL LIST________________________LISTPRINT BEGIN_____"<<endl;
	for (temp = GlobalList.begin();temp!= GlobalList.end();temp++)
	{
		cout<<"Iteration "<<iter<<endl;
		cout<<"HostPort "<<(*temp)->Port<<endl;
		cout<<"UOID: ";
		for (int iter1 = 0;iter1 <20;iter1++)
		{
			printf("%02x",(unsigned char)((*temp)->UOID)[iter1]);}cout<<endl;
			iter++;
	}
	cout<<"______________GLOBALLIST__________________LISTPRINTEND________"<<endl;
	return;
}
	
//------------------------------------------------------Print my list NeighborList END--------------------------------------------------------//

//------------------------------------------------------Print my list SocketList BEGIN----------------------------------------------------------//
void print_SocketList()
{
   int iter1=1;
   My570ListElem* temp1 = new My570ListElem();

   cout<<"______________SOCKETLIST________________________________LIST PRINT BEGIN____"<<endl;
   for(temp1=SocketList->First();temp1!=NULL;temp1=SocketList->Next(temp1))	
	{
	   cout<<"Iteration "<<iter1<<endl;
	   cout<<"Socket ID "<<(int)(temp1->Obj())<<endl;
	   iter1++;
	}
	cout<<"______________SOCKETLIST________________________________LIST PRINT END_____"<<endl;

return;
}

//------------------------------------------------------Print my list SocketList END----------------------------------------------------------//

//------------------------------------------------------Print my list EventQ Begin------------------------------------------------------------//
/*void print_EventQ()
{
   int iter1=1;
   My570ListElem* temp1 = new My570ListElem();

   cout<<"______________EVENTQ________________________________LIST PRINT BEGIN____"<<endl;
   for(temp1=EventQ->First();temp1!=NULL;temp1=EventQ->Next(temp1))	
	{
	   cout<<"Iteration "<<iter1<<endl;
	   cout<<"PORT "<<(unsigned short)(((Flood_Elem*)(temp1->Obj()))->Port)<<endl;
	   cout<<"UOID ";
	   for(int iter=0;iter<20;iter++){
			printf("%02x",(unsigned char)(((Flood_Elem*)(temp1->Obj()))->UOID)[iter]);}cout<<endl;
       cout<<"HOST LOCATION "<<(unsigned int)((Flood_Elem*)(temp1->Obj()))->HostLocation<<endl;
	   cout<<"TTL "<<(int)(((Flood_Elem*)(temp1->Obj()))->TTL)<<endl;
	   iter1++;
	}
	cout<<"______________EVENTQ________________________________LIST PRINT END_____"<<endl;

return;
}


*/

//------------------------------------------------------Print my list EventQ Begin------------------------------------------------------------//

// ----------------------------------------------------- SocketList Function ----------------------------------------------------------------//
void print_InitNeighborList()
{
	My570ListElem* elem = new My570ListElem();
    
	cout<<"--------------------------------------------INITNEIGHBORLIST----------------"<<endl;
	for(elem=InitNeighborList->First();elem!=NULL;elem=InitNeighborList->Next(elem))
	{
		cout<<"PORT "<<((InitNeighborList_Elem*)(elem->Obj()))->Port<<endl;
		//cout<<"DISTANCE "<<((InitNeighborList_Elem*)(elem->Obj()))->Distance<<endl;
	}
	cout<<"--------------------------------------------INITNEIGHBORLIST----------------"<<endl;
	return;
}
void killSocketList()
{
	My570ListElem* curr_sock = new My570ListElem();

	for(curr_sock=SocketList->First();curr_sock!=NULL;curr_sock=SocketList->Next(curr_sock))
	{
		close((int)(curr_sock->Obj()));
        SocketList->Unlink(curr_sock); 
	}
	return;
}
void Parse_InitN()
{
	string vstring;
	string temp;
	unsigned short port;
	FILE * fp = fopen(InitLocation.c_str(),"r");
	if(fp==NULL){
		cerr<<"init_neighbor_list can not be opened"<<endl;
	}else{
		char mystring[1000];
		while(fgets(mystring,sizeof(mystring),fp)!=NULL)
		{
			vstring = string(mystring);
			int i = vstring.find_first_of(":");
			temp = vstring.substr(i+1,vstring.length()-i-1);
			port = atoi(temp.c_str());
			InitNeighborList_Elem* ielem = new InitNeighborList_Elem();
			ielem->Port=port;
			ielem->Distance=0;
            InitNeighborList->Append((void *)ielem);
            vstring.clear(); 
            temp.clear();
		}
	}//else
	return ;
}


//-------------------------------------------------------Timer function Begin ---------------------------------------------------------//
void *Timer_func(void *threadarg)
{
	sleep((int)threadarg);
	//cout<<"After sleeping"<<endl;
	MyTimerFlag = 1;
	pthread_exit(NULL);
}
//-------------------------------------------------------Timer function End ---------------------------------------------------------//
//-------------------------------------------------------- Join Functions Begin -------------------------------------------------------------//
static
void BubbleForward(My570List *pList, My570ListElem **pp_elem1, My570ListElem **pp_elem2)
    /* (*pp_elem1) must be closer to First() than (*pp_elem2) */
{
    My570ListElem *elem1=(*pp_elem1), *elem2=(*pp_elem2);
    void *obj1=elem1->Obj(), *obj2=elem2->Obj();
    My570ListElem *elem1prev=pList->Prev(elem1);
/*  My570ListElem *elem1next=pList->Next(elem1); */
/*  My570ListElem *elem2prev=pList->Prev(elem2); */
    My570ListElem *elem2next=pList->Next(elem2);

    pList->Unlink(elem1);
    pList->Unlink(elem2);
    if (elem1prev == NULL) {
        (void)pList->Prepend(obj2);
        *pp_elem1 = pList->First();
    } else {
        (void)pList->InsertAfter(obj2, elem1prev);
        *pp_elem1 = pList->Next(elem1prev);
    }
    if (elem2next == NULL) {
        (void)pList->Append(obj1);
        *pp_elem2 = pList->Last();
    } else {
        (void)pList->InsertBefore(obj1, elem2next);
        *pp_elem2 = pList->Prev(elem2next);
    }
}



static
void BubbleSortForwardList(My570List *pList)
{
    My570ListElem *elem=NULL;
    int i=0;

    for (i=0; i < pList->Length(); i++) {
        int j=0, something_swapped=FALSE;
        My570ListElem *next_elem=NULL;

        for (elem=pList->First(), j=0; j < pList->Length()-i-1; elem=next_elem, j++) {
            unsigned int cur_val=((InitNeighborList_Elem*)(elem->Obj()))->Distance, next_val=0;

            next_elem=pList->Next(elem);
            next_val = ((InitNeighborList_Elem*)(next_elem->Obj()))->Distance;

            if (cur_val > next_val) {
                BubbleForward(pList, &elem, &next_elem);
                something_swapped = TRUE;
            }
        }
        if (!something_swapped) break;
    }
}
/*void print_InitNeighborList()
{
	My570ListElem* elem = new My570ListElem();
    
	cout<<"--------------------------------------------INITNEIGHBORLIST----------------"<<endl;
	for(elem=InitNeighborList->First();elem!=NULL;elem=InitNeighborList->next(elem))
	{
		cout<<"PORT "<<((InitNeighborList_Elem*)(elem->Obj()))->Port<<endl;
		cout<<"DISTANCE "<<((InitNeighborList_Elem*)(elem->Obj()))->Distance<<endl;
		cout<<endl;
	}
	cout<<"--------------------------------------------INITNEIGHBORLIST----------------"<<endl;
	return;
}*/
void *timerthread(void *threadarg)
{
	sleep(i1->JoinTimeout);
	MyTimerFlag=1;
	pthread_exit(NULL);
}
void *NonBeacon_Join(void *threadarg)
{
	MyTimerFlag=0;
	//-------------------------------------signals
	act.sa_handler =alrm2;
	sigaction(SIGALRM, &act, NULL);
	pthread_sigmask(SIG_UNBLOCK, &sigalrm, NULL);

	//-------------------------------------------
	int ret;
	int sockfd = (int)threadarg;
	pthread_t readt,writet;
	list<beacon>::iterator it;
	struct stat st;
    InitLocation = (string(HomeDir1)).substr(0,(int)strlen(HomeDir1)-1);
	if(InitFilename1==NULL){
		InitLocation = InitLocation + "/init_neighbor_list";
	}else{
		string InitTerminal = (string(InitFilename1)).substr(0,(int)strlen(InitFilename1)-1);
		InitLocation = InitLocation + InitTerminal;
	}	

	if (stat(InitLocation.c_str(),&st)!=0)
	{

		for (it=i1->BeaconList.begin(); it!=i1->BeaconList.end(); it++)
		{
			int JoinSock=0;
			struct sockaddr_in join_addr;
			JoinSock = socket(AF_INET,SOCK_STREAM,0);
			if (JoinSock < 0)
			{
				//perror("Socket");
				exit(1);
			}
			memset(&join_addr,0,sizeof (join_addr));
			join_addr.sin_family = AF_INET;
			join_addr.sin_port = htons((*it).BeaconPort);

			if (connect(JoinSock, (struct sockaddr *)&join_addr,sizeof(join_addr))<0)
			{
				close(JoinSock);
			}else{
				
				//--------------------------TIMER THREAD-----------JOIN TIMEOUT----------//

				struct HEADER join;
				join.MessageType=JNRQ;
				//unsigned char *UOIDstr1 = new unsigned char[20];
				//UOIDstr1 = GetUOID(node_instance_id,"msg");
				join.UOID = new unsigned char[20];
				//cout<<"Here "<<endl;
				//exit(1);
				memcpy(join.UOID,GetUOID(node_instance_id,"msg"),20);
				
				   
				int i=30;
				if(i1->TTL==0){join.TTL=(unsigned char)i;}else{join.TTL=(unsigned char)i1->TTL;}
				join.Reserved=(unsigned char)0;
				struct JOIN_MSG msg;
				msg.HostPort=i1->Port;
				msg.HostName=hostname;
				msg.HostLocation = i1->Location;
				join.DataLength=(int)strlen(msg.HostName)+2+4;
				
				socklen_t len;
				struct sockaddr_in peer;
				len = sizeof peer;
				getpeername(JoinSock, (struct sockaddr*)&peer, &len);
				struct sockaddr_in sa;
				int sock_len;
				sock_len = sizeof(sa);
				getsockname(JoinSock,(struct sockaddr *)&sa,(socklen_t *)&sock_len);
				unsigned char* JoinMessage = new unsigned char[512];
				memset(JoinMessage,'\0',512);
				memcpy(&JoinMessage[0],&join.MessageType,1);
				memcpy(&JoinMessage[1],join.UOID,20);
				memcpy(&JoinMessage[21],&join.TTL,1);
				memcpy(&JoinMessage[22],&join.Reserved,1);
				memcpy(&JoinMessage[23],&join.DataLength,4);
				memcpy(&JoinMessage[27],&msg.HostLocation,4);
				memcpy(&JoinMessage[31],&msg.HostPort,2);
				memcpy(&JoinMessage[33],&msg.HostName,strlen(msg.HostName));
				for (unsigned int it4 = 0;it4<27 ;it4++ )
				{
					if (send(JoinSock,&JoinMessage[it4],1,0)==-1)
					{
						//perror("nonbeacon: write");
						exit(1);
					}
				}
				  
				for (unsigned int it5 = 27;it5<27+join.DataLength; it5++ )
				{
					if (send(JoinSock,&JoinMessage[it5],1,0)==-1)
					{
						//perror("nonbeacon: write");
						exit(1);
					}
				}

							//---------------------------------------------- RESET----------------------------------------------------//
				pthread_mutex_lock(&log_lock);
				FILE *Log4 = fopen(LogLocation.c_str(),"a");
				if(Log4==NULL)
				{
					cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
				}else{
				gettimeofday(&tim,NULL);
				fprintf(Log4,"s %10ld.%03d nunki.usc.edu_%d JNRQ %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),ntohs(peer.sin_port),(int)(join.TTL));
					for(int pr=16;pr<20;pr++){fprintf(Log4,"%02x",(join.UOID)[pr]);}
				fprintf(Log4," %d nunki.usc.edu\n",msg.HostPort);
				fflush(Log4);
				}
				fclose(Log4);
				pthread_mutex_unlock(&log_lock);
				//---------------------------------------------------------------------------------------------------------//
				//int thrd_Timer;

				//pthread_t Timer_thread;
				//pthread_attr_init(&attr);
				//pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
				if (i1->JoinTimeout == 0)
				{
					i1->JoinTimeout = 15;
				}
				//cout<<"JOin Timeout"<<i1->JoinTimeout<<endl;
	//			thrd_Timer = pthread_create(&Timer_thread,&attr,Timer_func,(void *)i1->JoinTimeout);

				if (i1->MinNeighbors == 0)
				{
					i1->MinNeighbors = 2;
				}
				if (i1->InitNeighbors==0)
				{
					i1->InitNeighbors = 3;
				}
				//cout<<"Init Neighbors: "<<i1->InitNeighbors<<endl;
				//cout<<"Min Neighbors: "<<i1->MinNeighbors<<endl;
				int myTimerCount=0;
				fd_set rset_new;
				FD_ZERO(&rset_new);
			   FD_SET(JoinSock,&rset_new);
			   timeval timeout;
			   timeout.tv_sec = i1->JoinTimeout;
			   timeout.tv_usec = 100000;//100 ms Timer
				int thrd_timer;
				pthread_t timer;
				//-------------------------------------JOIN REPLY READ---------------------BEGIN----///
					while(MyTimerFlag!=1){
				//	alarm(i1->JoinTimeout);
					thrd_timer=pthread_create(&timer,&attr,timerthread,(void*)NULL);
					if(thrd_timer){
						cerr<<"Error; return code from thread Server create call is"<<thrd_timer<<endl;
						exit(-1);
					}
					//cout<<"Here"<<endl;

					unsigned char *JoinReply = new unsigned char[512];
					struct HEADER join2;
					struct JOIN_RES reply;
					memset(&join2,0,sizeof join);
					memset(&reply,0,sizeof reply);
					join2.UOID = new unsigned char[20];
					FD_ZERO(&rset_new);
					FD_SET(JoinSock,&rset_new);
					timeval timeout;
					timeout.tv_sec = i1->JoinTimeout;
					timeout.tv_usec = 100000;//100 ms Timer

					 if(select(JoinSock+1, &rset_new, NULL, NULL, &timeout) < 0)
					{

                       //printf("ERROR:Select Read socket error");
                       //close(JoinSock);
                      // pthread_exit(NULL);
					}
					if (MyTimerFlag == 1)
					{
						//cout<<"MyTimerFlag "<<MyTimerFlag<<endl;
						break;				
					}

					int numbytes = 0;

					for (unsigned int it3 = 0;it3<27;it3++)
					{
						if (FD_ISSET(JoinSock, &rset_new))
						{
						//cout<<"Here"<<end;
						if ((numbytes = read(JoinSock,&JoinReply[it3],1))==-1)
						{
							//perror("nonbeaconread");
							if (errno == 4)
							{
								break;
							}//exit(1);
						}
					}
					}
					if (MyTimerFlag == 1)
					{
						break;
					}
					if (numbytes == 0)
					{
						usleep(100);
						continue;
					}
					
					memcpy(&join2.MessageType,&JoinReply[0],1);
					memcpy(join2.UOID,&JoinReply[1],20);
					memcpy(&join2.TTL,&JoinReply[20],1);
					memcpy(&join2.Reserved,&JoinReply[21],1);
					memcpy(&join2.DataLength,&JoinReply[22],4);

					reply.UOID = new unsigned char[20];
					reply.HostName = new char[13];
					for (unsigned int it4 = 27;it4<27+39;it4++ )
					{				

						if ((numbytes = read(JoinSock,&JoinReply[it4],1))==-1)
						{
							//perror("nonbeacon: read");
							exit(1);
						}
					}
					memcpy(reply.UOID,&JoinReply[27],20);
					memcpy(&reply.Distance,&JoinReply[47],4);
					memcpy(&reply.HostPort,&JoinReply[51],2);
					memcpy(reply.HostName,&JoinReply[53],13);
                   
				//---------------------------------------------- RESET----------------------------------------------------//
				pthread_mutex_lock(&log_lock);
				FILE *Log3 = fopen(LogLocation.c_str(),"a");
				if(Log3==NULL)
				{
					cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
				}else{
				gettimeofday(&tim,NULL);
						fprintf(Log3,"r %10ld.%03d nunki.usc.edu_%d JNRS %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),reply.HostPort,(int)(join2.TTL));
					for(int pr=16;pr<20;pr++){fprintf(Log3,"%02x",(join2.UOID)[pr]);}
				fprintf(Log3," ");
				for(int pr=16;pr<20;pr++){fprintf(Log3,"%02x",(reply.UOID)[pr]);}
				fprintf(Log3," %d %d nunki.usc.edu\n",reply.Distance,reply.HostPort);
				fflush(Log3);
				}
				fclose(Log3);
				pthread_mutex_unlock(&log_lock);
				//---------------------------------------------------------------------------------------------------------// 

					pthread_mutex_lock(&PrintLock);
					pthread_mutex_unlock(&PrintLock);
					MyTimerCount++;
					InitNeighborList_Elem *neighbor = new InitNeighborList_Elem();
					//cout<<"JOIN REQUEST UOID: ";
					for (int ite = 0;ite<20;ite++)
					{
						//printf("%02x",reply.UOID[ite]);
					}//cout<<endl;			
					//cout<<"JOIN RESPONSE UOID: ";
					for (int ite = 0;ite<20;ite++)
					{
						//printf("%02x",join2.UOID[ite]);
					}//cout<<endl;							
					neighbor->Port = reply.HostPort;
					neighbor->Distance = reply.Distance;
					InitNeighborList->Append((void *)neighbor);
					//cout<<"Message received"<<endl;
					myTimerCount++;
				}//end while
				if (myTimerCount<i1->InitNeighbors)
				{
					exit(1);
				}
				BubbleSortForwardList(InitNeighborList);
				pthread_mutex_lock(&PrintLock);
				//print_InitNeighborList();
				pthread_mutex_unlock(&PrintLock);
				My570ListElem * curr = new My570ListElem();
				
				FILE *INL = fopen(InitLocation.c_str(),"w");
				int myCount=0;

				for(curr = InitNeighborList->First(); curr !=NULL;curr=InitNeighborList->Next(curr))
				{
					myCount=myCount+1;
					fprintf(INL,"nunki.usc.edu:%d\n",((InitNeighborList_Elem*)(curr->Obj()))->Port);

					if(myCount==(i1->InitNeighbors))
					{
						if(InitNeighborList->Next(curr)!=NULL){
							My570ListElem *relem = new  My570ListElem();
							for(relem = InitNeighborList->Next(curr); relem!=NULL; relem=InitNeighborList->Next(relem))
							{
								InitNeighborList->Unlink(relem);
							}
						}
						break;
					}
					
				}
				fclose(INL);

			}//end connection successful
			close(JoinSock);
			break;
			
		}//end for over i1
	}//END FILE PRESENT
	Parse_InitN();
	pthread_mutex_lock(&PrintLock);
	//print_InitNeighborList();
	//cout<<"Before connecting.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"<<InitNeighborList->Length()<<endl;

	pthread_mutex_unlock(&PrintLock);
	//exit(1);
	//list<InitNeighborList_Elem*>::iterator NLit;
	My570ListElem * curr = new My570ListElem();

	for(curr = InitNeighborList->First(); curr !=NULL;curr=InitNeighborList->Next(curr))//for (NLit = InitNeighborList.begin();NLit!=InitNeighborList.end();NLit++ )
	{

		if(AutoShutDown==1){break;}
		//cout<<"Iteration: "<<endl;
		while (!AutoShutDown)
		{
			int newsock=0;
			
			struct sockaddr_in serv_addr;
			
			//---------------------------------  CREATING THE SOCKET TO CONNECT TO OTHER BEACONS ----------------//
			newsock = socket(AF_INET,SOCK_STREAM,0);
			if (newsock < 0)
			{
				//perror("Socket");
				exit(1);
			}
			memset(&serv_addr,0,sizeof (serv_addr));
			serv_addr.sin_family = AF_INET;
			serv_addr.sin_port = htons(((InitNeighborList_Elem*)(curr->Obj()))->Port);
			//cout<<"connecting to "<<serv_addr.sin_port<<endl;
			//exit(1);
			if (serv_addr.sin_port == i1->Port)
			{
				close(newsock);
				break;
			}
			if (connect(newsock, (struct sockaddr *)&serv_addr,sizeof(serv_addr))<0)
			{
				usleep(100);
				close(newsock);
				//break;
				//delete init_neighbor_list and do join again
			}else{
				
				activeconnection = 1;
			//	cout<<"Connected to "<<serv_addr.sin_port<<endl;
				
				struct sockaddr_in sa;
				int sock_len;
				sock_len = sizeof(sa);
				getsockname(newsock,(struct sockaddr *)&sa,(socklen_t *)&sock_len);

				//////CREATE HELLO PACKET/////
				struct HEADER hello;
				struct HELLO_MSG msg;

				hello.UOID = new unsigned char[20];
				hello.MessageType=HLLO;
				//cout<<"UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU___________________________________"<<endl;
				for(int it2=0;it2<20;it2++){
					hello.UOID[it2]=(GetUOID(node_instance_id,"msg"))[it2];
			//			printf("%02x",(unsigned char)hello.UOID[it2]);
				}
				//cout<<endl;
                
				int i=30;
				if(i1->TTL==0){hello.TTL=(unsigned char)i;}else{hello.TTL=(unsigned char)i1->TTL;}
				
				hello.Reserved=(unsigned char)0;
                msg.HostPort=i1->Port;
				msg.HostName=hostname;
				hello.DataLength=(int)strlen(msg.HostName)+2;//intLength((int)msg.HostPort);

				unsigned char* HelloMessage = new unsigned char[512];
				memset(HelloMessage,'\0',512);
				memcpy(&HelloMessage[0],&hello.MessageType,1);
                memcpy(&HelloMessage[1],hello.UOID,20);
				memcpy(&HelloMessage[21],&hello.TTL,1);
				memcpy(&HelloMessage[22],&hello.Reserved,1);
				memcpy(&HelloMessage[23],&hello.DataLength,4);
				memcpy(&HelloMessage[27],&msg.HostPort,2);
				memcpy(&HelloMessage[29],&msg.HostName,strlen(msg.HostName));
				
				//cout<<"Host port being sent from connect "<<msg.HostPort<<endl;
				/////////////////////////// END HELLO PACKET CREATION//////////////

					
					//---------------------------- SENDING HELLO MESSAGE FROM THE CONNECT THREAD BEGIN ---------------------------//
					for (unsigned int it4 = 0;it4<27 ;it4++ )
					{
						if (send(newsock,&HelloMessage[it4],1,0)==-1)
						{
							//perror("beaconconnect: write");
							exit(1);
						}

					}
					for (unsigned int it5 = 27;it5<27+hello.DataLength; it5++ )
					{
						if (send(newsock,&HelloMessage[it5],1,0)==-1)
						{
							//perror("beaconconnect: write");
							exit(1);
						}
					
					}
					//cout<<"SENT MESSAGE from "<<(int) ntohs(sa.sin_port)<<" to "<<serv_addr.sin_port<<endl;

					//---------------------------------------------- RESET----------------------------------------------------//
				pthread_mutex_lock(&log_lock);
				FILE *Log = fopen(LogLocation.c_str(),"a");
				if(Log==NULL)
				{
					cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
				}else{
				if (serv_addr.sin_port != i1->Port){
				gettimeofday(&tim,NULL);
				fprintf(Log,"s %10ld.%03d nunki.usc.edu_%d HLLO %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),ntohs(serv_addr.sin_port),(int)(hello.TTL));
				for(int pr=16;pr<20;pr++){fprintf(Log,"%02x",hello.UOID[pr]);}
				fprintf(Log," %d nunki.usc.edu\n",msg.HostPort);
				fflush(Log);
				}
				}
				fclose(Log);
				pthread_mutex_unlock(&log_lock);
				//---------------------------------------------------------------------------------------------------------//
					//---------------------------- RECEIVING HELLO MESSAGE RESPONSE BEGIN ----------------------------------------//
				//	exit(1);
					unsigned char * HelloReceived = new unsigned char[512];
					struct HEADER helloRecvd;
					struct HELLO_MSG RecvdMsg;
					
					memset(&helloRecvd,0,sizeof helloRecvd);

					int numbytes;
					for (unsigned int it6 = 0;it6<27 ;it6++ )
					{
						if ((numbytes = read(newsock, &HelloReceived[it6], 1))<0)
						{
							//perror("read");
							//break;
							//exit(1);	
						}
					}
					if (serv_addr.sin_port == i1->Port)
					{
						close(newsock);
						break;
					}
					if (numbytes == 0)
					{
						usleep(100);
						close(newsock);

						break;
					}
					else{
					
					helloRecvd.UOID = new unsigned char[20];

					//---------------------------- RECEIVING HELLO MESSAGE RESPONSE END ----------------------------------------//
					memcpy(&helloRecvd.MessageType,&HelloReceived[0],1);
					memcpy(helloRecvd.UOID,&HelloReceived[1],20);
					memcpy(&helloRecvd.TTL,&HelloReceived[21],1);
					memcpy(&helloRecvd.Reserved,&HelloReceived[22],1);
					memcpy(&helloRecvd.DataLength,&HelloReceived[23],4);
					//cout<<"UUUUUUUUUUUUUUUUOOOOOOOOOOOOOOOOOOOOIIIIIIIIIIIIIIIIIIIIIIIIIDDDDDDDDDDDDDDDDDDDDDD"<<endl;
					for(int it2=0;it2<20;it2++){
			//			printf("%02x",(unsigned char)helloRecvd.UOID[it2]);
					}
					//cout<<endl;
					for (unsigned int it3 = 27;it3<27+helloRecvd.DataLength ;it3++ )
					{
						if ((numbytes = read(newsock, &HelloReceived[it3], 1))==-1)
						{
						//	perror("read");
						}
					}
					memcpy(&RecvdMsg.HostPort,&HelloReceived[27],2);
					memcpy(&RecvdMsg.HostName,&HelloReceived[29],helloRecvd.DataLength-2);
					//cout<<"Received hello response from "<<RecvdMsg.HostPort<<endl;

                    
					//---------------------------------------------- RESET----------------------------------------------------//
				pthread_mutex_lock(&log_lock);
				FILE *Log2 = fopen(LogLocation.c_str(),"a");
				if(Log2==NULL)
				{
					cerr<<"Log file can not be opened. The program will continue without logging."<<endl;
				}else{
				if (serv_addr.sin_port != i1->Port){
				gettimeofday(&tim,NULL);
				fprintf(Log2,"r %10ld.%03d nunki.usc.edu_%d HLLO %d ",(tim.tv_sec),(int)((tim.tv_usec)/1000),RecvdMsg.HostPort,(int)(helloRecvd.TTL));
				for(int pr=17;pr<21;pr++){fprintf(Log2,"%02x",HelloReceived[pr]);}
				fprintf(Log2," %d nunki.usc.edu\n",RecvdMsg.HostPort);
				fflush(Log2);
				}
				}
				fclose(Log2);
				pthread_mutex_unlock(&log_lock);
				//---------------------------------------------------------------------------------------------------------//
                      

						//exit(1);
					//----------------------------------------------- BUILD ELEM FOR NEIGHBOR LIST -------------------------------//
					
						NeighborList_Elem* elem1 = new NeighborList_Elem();
						elem1->UOID = new unsigned char[20];
						memcpy(elem1->UOID,&HelloReceived[1],20);
						memcpy(&(elem1->HostPort),&HelloReceived[27],2);
	
					// Loop Test Print/UOID  for(int it2=0;it2<20;it2++){printf("%02x",(unsigned char)(elem1->UOID)[it2]);}cout<<endl;cout<<elem1->HostPort<<endl;exit(1);
					
					//----------------------------------------------BUILD ELEM FOR NEIGHBOR LIST END TESTED CHECKED-----------------------------//
					
					//ACQUIRE A LOCK ON THE NEIGHBOR LIST AND APPEND THE NEIGHBOR INTO THE LIST
					pthread_mutex_lock(&NeighborList_lock);
//					for(int it2=0;it2<20;it2++){printf("%02x",(unsigned char)(elem1->UOID)[it2]);}cout<<endl;cout<<elem1->HostPort<<endl;
					NeighborList->Append((void *)elem1);
					Duplicate = eval_Duplicate();
					//print_NeighborList();
					if (Duplicate == 0)
					{
				//		cout<<"Duplicate found on beaconconnect"<<endl;
					}
					pthread_mutex_unlock(&NeighborList_lock);
					//------------------------------ APPENDING NEIGHBORS FOR DUPLICATES END ---------------------------------------//

					pthread_mutex_lock(&SocketList_lock);
					SocketList->Append((void*)newsock);
					pthread_mutex_unlock(&SocketList_lock);
					//------------------------------ APPENDING TO GLOBAL LIST ----------------------------------------------------//

					//My570List *EventQ = new My570List();
					list<Flood_Elem*>* EventQ = new list<Flood_Elem*>;
					GlobalList_Elem *Gelem = new GlobalList_Elem();
					Gelem->UOID = new unsigned char[20];
					Gelem->ListP = *EventQ;
					Gelem->Port =  RecvdMsg.HostPort;
					Gelem->Temp = 0;
					Gelem->Socket=newsock;
					memcpy(Gelem->UOID,&HelloReceived[1],20);

					//cout<<"Putting "<<Gelem->Port<<" into Global list"<<endl;
					pthread_mutex_lock(&GlobalList_lock);
					GlobalList.push_back(Gelem);
					dupGlobal = eval_Global();
			//		print_GlobalList();
					pthread_mutex_unlock(&GlobalList_lock);

					//------------------------------ APPENDING TO GLOBAL LIST ----------------------------------------------------//
					//cout<<"newsock1 "<<newsock<<" connected to "<<RecvdMsg.HostPort<<endl;

					if ((ret = pthread_create(&readt,NULL,readthread,(void *)Gelem)))
					{
						//error has occurred
						fprintf(stderr,"Error:pthread_create, %s\n",strerror(ret));
						exit(1);
					}
					//cout<<"newsock2 "<<newsock<<" connected to "<<RecvdMsg.HostPort<<endl;

					if ((ret = pthread_create(&writet,NULL,writethread,(void *)Gelem)))
					{
						//error has occurred
						fprintf(stderr,"Error:pthread_create, %s\n",strerror(ret));
						exit(1);
					}
						
					//cout<<"Connected to "<<serv_addr.sin_port<<endl;

					break;
					
					}//end else condition numbytes =0

			}//end else connect	
		}//end while(1)
		//break;
	}//end for
	//int ret;
	//cout<<"sadjflkjasl;kjfl;aksjfl;kajsfdlkj______++++++++++++++++++++++++++++++++++++@@@@@@@@@@@@@@@@@@@"<<endl;
	pthread_t server_thread;
	if ((ret = pthread_create(&server_thread,NULL,serverthread,(void *)sockfd)))
	{
		//error has occurred
		fprintf(stderr,"Error:pthread_create, %s\n",strerror(ret));
		exit(1);
	}
	int  thrd_st=0;
    void *status_st;
	thrd_st = pthread_join(server_thread,&status_st);
	if(thrd_st){
		cerr<<"Error; return code from thread Server join call inside non beacon is "<<thrd_st<<endl;
		exit(-1);
	}
	//cout<<"broken from non beacon";
	return 0;
}//end void NonNeacon_Join()


//-------------------------------------------------------------------Join Function: Duplicate_Event ------------------------------------------------//

int Duplicate_Event(Flood_Elem *fd_obj,list<Flood_Elem*> EventQ)
{
	list<Flood_Elem*>::iterator it;
    if(EventQ.size()==0)
	{return 0;}else;

	for(it=EventQ.begin();it!=EventQ.end();it++)
	{

	}


	exit(1);

}


//-------------------------------------------------------------------Join Function: Duplicate_Event ------------------------------------------------//

//-------------------------------------------------------------------Join Function: FLOOD BEGIN ---------------------------------------------------//



int Check_Node(int thisPort)
{
	list<beacon>::iterator it;
	for (it=i1->BeaconList.begin(); it!=i1->BeaconList.end(); it++){

       if(thisPort==(*it).BeaconPort){
		   return 1;// beacon
	   }
	}
	return 0; //non beacon

}



//-------------------------------------------------------------------Join Function: FLOOD End ----------------------------------------------------//

//-------------------------------------------------------------------Join Functions End ----------------------------------------------------//
